/*
 * PlayerModel.java
 *
 * @author Michael Hansen
 * @author Lukas Thuernagel
 * @author Soeren Warszus
 */

package risk.player;

import java.awt.Color;
import risk.card.Card;
import risk.game.Territory;
import risk.game.Continent;
import risk.game.RiskModel;
import risk.messagebox.MessageBox;
import java.util.*;
import java.lang.String.*;
import javax.swing.*;
import risk.game.*;

public class PlayerModel {
    
    // Spielername
    private String playerName;
    
    // Spielerfarbe 
    private Color playerColor;
    
    /**
     * View, das dieses Model (Spieler) auf dem Board darstellt
     */
    private PlayerView boardView;
    
    /**
     * View, dieses Model (Spieler) zur darstellen der karten
     */
    private PlayerCardView pcv;
    
    /**
     * Liste der gesammelten Spielkarten dieses Spielers
     */
    private ArrayList<Card> alCard;
    
    /**
     * Liste der Laender, die im Besitz des Spielers sind.
     */
    private ArrayList<Territory> alTerritories;
    
    /**
     * Liste der Kontinente, die im Besitz des Spielers sind.
     */
    private ArrayList<Continent> alContinents;
    
    /**
     * Anzahl der verfuegbaren Truppen
     */
    private int unitCount;
    
    /**
     * 
     */
    private boolean unitSetted = false;
    
    /**
     * Angabe der Phase, in der sich der Spieler befindet
     */
    private int state;

    private PlayerCard pc;
    
    
    /**
     * Konstruktor zum Anlegen eines neuen Spielers
     * @param name Name des Spielers
     * @param color Farbe zur Identifikation des Spielers
     */
    public PlayerModel(String name, Color color) {
        this.playerName = name;
        this.playerColor = color;
        this.alCard = new ArrayList<Card>();
        alTerritories = new ArrayList();
        alContinents = new ArrayList();
    }
    
     /**
     * Registrieren des Views, das diesen Spieler auf dem
     * Spielbrett anzeigt.
     *
     * @param PlayerView pv  Zu diesem Model zugehoeriger View auf dem Board
     */
    public void registerBoardView(PlayerView pv){
        if (pv == null) {
            throw new IllegalArgumentException("Cannot add null object to PlayerModel");
        }
        this.boardView = pv;
    }
    
    public void registerPlayerCardView(PlayerCard pc, PlayerCardView pcv){
        if (pcv == null) {
            throw new IllegalArgumentException("Cannot add null object to PlayerModel");
        }
        this.pc = pc;
        this.pcv = pcv;
    }
    
    /**
     * Ausgabe der Anzeige des Spielers auf dem Spielbrett
     *
     * @return PlayerView Die Anzeige des Spielers auf dem Spielbrett
     */
    public PlayerCardView getCardView(){
        return this.pcv;
    }
    
    /**
     * Ausgabe der Anzeige des Spielers auf dem Spielbrett
     *
     * @return PlayerView Die Anzeige des Spielers auf dem Spielbrett
     */
    public PlayerCard getCardModel(){
        return this.pc;
    }
    
    /**
     * Ausgabe der Anzeige des Spielers auf dem Spielbrett
     *
     * @return PlayerView Die Anzeige des Spielers auf dem Spielbrett
     */
    public PlayerView getBoardView(){
        return this.boardView;
    }
    
    /**
     * Rueckgabe des Spielernamens
     *
     * @return String playerName
     */
    public String getPlayerName(){
        return this.playerName;
    }
    
    /**
     * Rueckgabe der Spielerfarbe
     *
     * @return Color playerColor
     */
    public Color getPlayerColor(){
        return this.playerColor;
    }
    
    /**
     * Setzen der Phase, in der sich der Spieler befindet
     *
     * @param int i Phase, 1 - Truppenverteilung, 2 - Kampfphase 3 - Truppenbewegung
     */
    public void setState(int i){
        this.state = i;
        if(this.boardView !=null){
            this.boardView.setState(this.getStateString());
        }
    }
    
    /**
     * Rueckgabe der Phase
     * 
     * @return int state Phase, in der sich der Spieler befindet 1 - Truppenverteilung, 2 - Kampfphase 3 - Truppenbewegung
     */
    public int getState(){
        return this.state;
    }
    
    /**
     * Rueckgabe der Phase als String
     *
     * @return String state
     */
    public String getStateString(){
        switch(state){
            case 1:{
                return "Truppenaufbau";
            }
            case 2:{
                return "Kampfphase";
            }
            case 3:{
                return "Truppenbewegung";
            }
            case 0:{
                return "Truppenverteilung";
            }
            default:{
                return "Phase unbekannt";
            }
        }
    }
    
    /**
     * Hinzufuegen einer neuen Karte nach Besetzung eines
     * neuen Territory. Karte wird der ArrayList<Card> zugefuegt.
     * 
     *
     * @param Card newCard Neu hinzuzufuegende Karte
     */
    public void setCard(Card newCard){
        if (alCard.size()<5)  
            this.alCard.add(newCard);
    }
    
    /**
     * Rueckgabe der Kartenlist
     *
     * @return ArrayList<Card> alCard Liste der gesammelten Karten
     */
    public ArrayList<Card> getCardList(){
        return this.alCard;
    }
    
    /**
     * Rueckgabe der Kartenanzahl
     *
     * @return int alCard.size() Anzahl der Karten
     */
    public int getCardCount (){
        return this.alCard.size();
    }
     
    /**
      * Hinzufuegen eines neuen Landes, was vom Spieler eingenommen wurde.
      * Land wird in der ArrayList<Territory> hinzugefuegt.
      *
      * @param Territory newTerritory Neu hinzuzufuegendes Land
      */
     public void setTerritory(Territory newTerritory){
         if (this != newTerritory.getOwner()){
             if(newTerritory.getOwner()==null){
                 newTerritory.setOwner(this);
             }
             this.alTerritories.add(newTerritory);
             if(this.boardView!=null){
                 this.boardView.updateView();
             }
         }
     }
     
     /**
      * Löscht das Landes aus der Territoryliste
      *
      * @param Territory oldTerritory Zu loeschende Land
      */
     public void deleteTerritory(Territory oldTerritory){
         for(int i=0;i<this.alTerritories.size();i++){
             if(this.alTerritories.get(i)==oldTerritory){
                 this.alTerritories.remove(i);
                 this.boardView.updateView();
                 i=this.alTerritories.size();
             }
         }
     }
     
     /**
     * Rueckgabe der Laenderliste
     *
     * @return ArrayList<Territory> alTerritories Liste der eingenommenen Laender
     */
     public ArrayList<Territory> getTerritoryList(){
         return this.alTerritories;
     }
     
     /**
     * Rueckgabe der Laenderanzahl
     *
     * @return int alTerritories.size() Anzahl der Laender
     */
     public int getTerritoryCount(){
         return this.alTerritories.size();
     }
     
     /**
      * Hinzufuegen eines neuen Kontinentes, welcher vom Spieler eingenommen wurde.
      * Kontinent wird in der ArrayList<Continent> hinzugefuegt.
      *
      * @param Continent newContinent Neu hinzuzufuegender Kontinent
      */
     public void setContinent(Continent newContinent){
         if (this == newContinent.getOwner()){
             this.alContinents.add(newContinent);
         }
     }
     
     /**
      * Löscht den Kontinent aus der Kontinentliste
      *
      * @param Continent oldContinent Zu loeschender Kontinent
      */
     public void deleteContinent(Continent oldContinent){
         for(int i=0;i<this.alContinents.size();i++){
             if(this.alContinents.get(i)==oldContinent){
                 this.alContinents.remove(i);
                 this.boardView.updateView();
                 i=this.alContinents.size();
             }
         }
     }
     
     /**
     * Rueckgabe der Kontinentliste
     *
     * @return ArrayList<Continent> alContinents Liste der eingenommenen Kontinente
     */
     public ArrayList<Continent> getContinentList(){
         return this.alContinents;
     }
     
     /**
     * Rueckgabe der Kontinentanzahl
     *
     * @return int alContinents.size() Anzahl der Kontinente
     */
     public int getContinentCount(){
         return this.alContinents.size();
     }
     
     /**
      * Erhoeht auf dem jeweiligen Land den Truppenbestand um 1,
      * wenn der Spieler der Besitzer diese Landes ist.
      *
      * @param Territory territory Land, auf welches eine Einheit platziert werden soll.
      * @return boolean Wahrheitswert, ob der Spieler eine Truppe gesetzt hat
      */
     public boolean setUnit(Territory territory){
         
         boolean unitSetted = false;
         if (this.getUnitCount() >= 1){
             if (territory.getOwner() == this){
                 territory.setArmySize(territory.getArmySize()+1);
                 this.setUnitCount(this.getUnitCount()-1);
                 unitSetted = true;
             }
             else{
                 //MessageBox msg = new MessageBox("Bitte eigenes Land waehlen", false);
                 //JOptionPane.showMessageDialog(null, "Bitte eigenes Land waehlen", "Message", JOptionPane.OK_CANCEL_OPTION);
             }
         }
         else{
             //MessageBox msg = new MessageBox("Sie haben keine Truppen mehr zu verteilen! Bitte nächster Spieler ;-)", false);
             //JOptionPane.showMessageDialog(null, "Sie haben keine Truppen mehr zu verteilen! Bitte nächster Spieler ;-)", "Message", JOptionPane.OK_CANCEL_OPTION);
         }
         return unitSetted;
     }
     
     /**
      * Gibt die Einheiten zurueck, ueber die der Spieler noch verfuegt.
      *
      * @return int unitCount Anzahl der verfuegbaren Einheiten
      */     
     public int getUnitCount(){
         return unitCount;
     }
     
     /**
      * Setzt den aktuellen Einheitenbestand fest.
      *
      * @param int i Anzahl der Einheiten, ueber die der Spieler verfuegen soll
      */
     public void setUnitCount(int i){
         this.unitCount = i;
     }

}

